package com.ironman.compute;

import cn.hutool.core.collection.CollectionUtil;
import com.ironman.common.entity.BaseData;
import com.ironman.common.structure.AngleVectorData;
import com.ironman.common.structure.AngleWindowData;
import com.ironman.common.structure.FixedSizeLinkedBlockingDeque;
import com.ironman.common.util.WindowAngleUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.stream.Collectors;


@Slf4j
public abstract class BaseVectorComputer<T extends BaseData> implements BaseComputer{

    private final FixedSizeLinkedBlockingDeque<T> linkedBlockingDeque;

    /**
     * 移动平均窗口大小
     */
    private final Integer windowSize;

    public BaseVectorComputer(int windowSize) {
        this.windowSize = windowSize;
        this.linkedBlockingDeque = new FixedSizeLinkedBlockingDeque<>(windowSize);
    }

    public void windowData(T t, BiConsumer<Date, Double> windowDataConsumer) {
        this.linkedBlockingDeque.offerLast(t);
        List<T> dataList = this.linkedBlockingDeque.subList(windowSize, true);
        if (CollectionUtil.isEmpty(dataList)) {
            log.warn("地图:未能达到窗口大小，目标窗口大小为{}", windowSize);
            return;
        }
        log.info("开启窗口计算 目标窗口大小 {} 实际数据大小 {}", windowSize, dataList.size());
        List<AngleVectorData> angleVectorDataList = dataList.stream().map(n -> WindowAngleUtil.preCompute(n.getTs(), n.calValue())).collect(Collectors.toList());
        AngleWindowData angleWindowData = WindowAngleUtil.computeAngleWindowData(angleVectorDataList);
        windowDataConsumer.accept(angleWindowData.getTs(), angleWindowData.getAngle());
    }
}
